
package com.lvmama.rhino.web;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.lvmama.rhino.enums.CommonParentType;
import com.lvmama.rhino.pojo.FlowStatisticsVo;
import com.lvmama.rhino.pojo.ProductDetail;
import com.lvmama.rhino.pojo.StatisticCode;
import com.lvmama.rhino.pojo.search.FlowSearchStation;
import com.lvmama.rhino.service.FlowSearchService;
import com.lvmama.rhino.service.FlowStatisticsService;
import com.lvmama.rhino.service.ProductDetailService;
import com.lvmama.rhino.service.StatisticCodeService;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.DecimalFormat;
import java.util.*;

/**
 * 
* @ClassName: ProductDetailController
* @Description: TODO 流量统计
* @author wangzhuoya
* @date 2017年5月22日 下午1:51:00
 */
@Controller
@RequestMapping("product")
public class ProductDetailController {

    @Autowired
	private ProductDetailService productDetailService;

    @Autowired
    private FlowSearchService flowSearchService;

    @Autowired
    private FlowStatisticsService flowStatisticsService;

    @Autowired
    private StatisticCodeService statisticCodeService;

	@RequestMapping("productDetail")
    public String productDetail(ModelMap model){
        //站点
        List<FlowSearchStation> stationList = flowSearchService.getStations();
        model.addAttribute("stationList", stationList);
        return "application/productDetail";
    }


    /**
     * 前50列
     * @param productDetail
     * @return
     */
    @RequestMapping("beforeFiftyProductList")
    @ResponseBody
    public Map<String, Object> getBeforeFiftyProductList(ProductDetail productDetail){
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<ProductDetail> productList = getDataList(productDetail);
        Collections.sort(productList, new Comparator<ProductDetail>() {
            @Override
            public int compare(ProductDetail o1, ProductDetail o2) {
                return o2.getAmount().compareTo(o1.getAmount());
            }
        });
        if(productList.size() > 50){
            productList = productList.subList(0,50);
        }
        PageInfo page = getListByPage(productList,productDetail.getPageSize(),productDetail.getPage());
        resultMap.put("page",page);
        return resultMap;
    }

    /**
     * 后50列
     * @param productDetail
     * @return
     */
    @RequestMapping("afterFiftyProductList")
    @ResponseBody
    public Map<String, Object> getAfterFiftyProductList(ProductDetail productDetail){
        Map<String, Object> resultMap = new HashMap<String, Object>();

        List<ProductDetail> productList = getDataList(productDetail);
        Collections.sort(productList, new Comparator<ProductDetail>() {
            @Override
            public int compare(ProductDetail o1, ProductDetail o2) {
                return o1.getAmount().compareTo(o2.getAmount());
            }
        });
        if(productList.size() > 50){
            productList = productList.subList(0,50);
        }
        PageInfo page = getListByPage(productList,productDetail.getPageSize(),productDetail.getPage());
        resultMap.put("page",page);
        return resultMap;
    }

    public List<ProductDetail> getDataList(ProductDetail productDetail){
        Map<String, Date> dateMap = getQueryDate(productDetail.getChooseTime());
        Date beginDate = dateMap.get("beginDate");
        Date endDate = dateMap.get("endDate");
        productDetail.setStartDate(beginDate);
        productDetail.setEndDate(endDate);
        if(StringUtils.isNotEmpty(productDetail.getCategoryName())){
            productDetail.setCategoryId(CommonParentType.getCategoryValueByShowName(productDetail.getCategoryName()));
        }
        if (StringUtils.isNotEmpty( productDetail.getStatisticCode())){
            List<String> statisticCodeList = null;
            if ("app".equals(productDetail.getStatisticCode())){
                statisticCodeList = statisticCodeService.getDeviceCodeApp();
            }else{
                statisticCodeList = statisticCodeService.getDeviceCodeByLikeName(productDetail.getStatisticCode());
            }
            if (statisticCodeList != null && statisticCodeList.size() > 0){
                productDetail.setStatisticCodeList(statisticCodeList);
            }
        }
        List<ProductDetail> productDetailList = productDetailService.getTableList(productDetail);
        List<ProductDetail> productList = new ArrayList<ProductDetail>();

        if (productDetailList != null && productDetailList.size() > 0) {
            Map<Object,ProductDetail> productDetailMap = new HashMap<Object,ProductDetail>();

            for(ProductDetail pro:productDetailList){
                JSONArray jsonData = null;
                try{
                    jsonData = JSONArray.parseArray(pro.getProductJson());
                }catch (Exception e){
                    System.out.println(pro.getProductJson());
                    e.getStackTrace();
                    continue;
                }
                for (int i = 0; i < jsonData.size(); i++) {

                    JSONArray jo = (JSONArray) jsonData.get(i);
                    ProductDetail productDetailVo = new ProductDetail();
                    productDetailVo.setProductId(jo.get(0).toString());
                    productDetailVo.setProductName(jo.get(1).toString());
                    productDetailVo.setAmount(Integer.parseInt(jo.get(2).toString()));
                    if(productDetailMap.containsKey(jo.get(0))){
                        productDetailMap.get(jo.get(0)).setAmount(productDetailMap.get(jo.get(0)).getAmount() + Integer.parseInt(jo.get(2).toString()));
                    }else{
                        productDetailMap.put(jo.get(0),productDetailVo);
                    }
                }

            }
            for (Map.Entry<Object,ProductDetail> entry : productDetailMap.entrySet()) {
                productList.add((ProductDetail)entry.getValue());
            }
        }

        return  productList;
    }

    /**
     *	产品详情页图表数据
     * @param
     * @param
     * @return
     * @throws Exception
     */
    @RequestMapping("productDetailChartData")
    @ResponseBody
    public Map<String, Object> productDetailChartData(ProductDetail productDetail)throws Exception{
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 查询日期条件处理
        Map<String, Date> dateMap = getQueryDate(productDetail.getChooseTime());
        Date beginDate = dateMap.get("beginDate");
        Date endDate = dateMap.get("endDate");
        productDetail.setStartDate(beginDate);
        productDetail.setEndDate(endDate);
        if (productDetail != null && productDetail.getStatisticCode() != null && !"".equals(productDetail.getStatisticCode()) ){
            List<String> statisticCodeList = null;
            if ("app".equals(productDetail.getStatisticCode())){
                statisticCodeList = statisticCodeService.getDeviceCodeApp();
            }else{
                statisticCodeList = statisticCodeService.getDeviceCodeByLikeName(productDetail.getStatisticCode());
            }
            if (statisticCodeList != null && statisticCodeList.size() > 0){
                productDetail.setStatisticCodeList(statisticCodeList);
            }
        }
        List<ProductDetail> list = productDetailService.getChartList(productDetail);
        JSONArray arr = new JSONArray();

        if(list.size() > 0){
            for (ProductDetail pro:list) {
                if(StringUtils.isNotEmpty(CommonParentType.getCategoryShowName(pro.getCategoryId()))){
                    JSONObject o = new JSONObject();
                    o.put("categoryName",CommonParentType.getCategoryShowName(pro.getCategoryId()));
                    o.put("amount",pro.getAmount());
                    arr.add(o);
                }
            }
        }
        resultMap.put("jsonData",arr);
        return resultMap;
    }


    /**
     * 追踪产品上下游相关信息
     * @param productDetail
     * @return
     */
    @RequestMapping("trackProduct")
    @ResponseBody
    public Map<String, Object> trackProduct(ProductDetail productDetail){
        Map<String, Object> resultMap = new HashMap<String, Object>();
        // 查询日期条件处理
        Map<String, Date> dateMap = getQueryDate(productDetail.getChooseTime());
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("start_date", dateMap.get("beginDate"));
        param.put("pageCurrentNum", productDetail.getPage());
        param.put("pageSize", productDetail.getPageSize());
        param.put("end_date", dateMap.get("endDate"));
        param.put("product_id",productDetail.getProductId() );
        List<FlowStatisticsVo> fromList = flowStatisticsService.queryFlowFromList(param).getList();
        List<FlowStatisticsVo> toList = flowStatisticsService .queryFlowToList(param).getList();


        for (FlowStatisticsVo flowStatisticsVo : fromList) {
            String code = flowStatisticsVo.getParent_page_code() != null ? flowStatisticsVo
                    .getParent_page_code() : "";
            if (code.equals("3XagQ") || code.equals("3TXDD")
                    || code.equals("3DaiZ") || code.equals("3ZhiW")) {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                // 获得相匹配的品类的信息
                String categoryId = CommonParentType
                        .getCategoryShowName(flowStatisticsVo
                                .getParent_category_id());
                if (StringUtils.isEmpty(categoryId)) {
                    categoryId = "其他";
                }
                flowStatisticsVo.setParent_category_id(categoryId);// 页面名称
                flowStatisticsVo.setParent_page_code(pageBusinessTypes);// 页面业务类型
            } else if (code.startsWith("3PinD") || code.startsWith("3zhTi")
                    || code.startsWith("3SouS")) {
                String category_id1 = "";
                if (code.startsWith("3PinD")) {
                    category_id1 = "3PinD";
                } else if (code.startsWith("3zhTi")) {
                    category_id1 = "3zhTi";
                } else if (code.startsWith("3SouS")) {
                    category_id1 = "3SouS";
                }
                StatisticCode statisticParentCode = new StatisticCode();
                statisticParentCode.setCode(category_id1);
                // 根据条件查询code对象
                statisticParentCode = statisticCodeService
                        .selectStatisticCode(statisticParentCode);
                String categoryId = "";// 页面业务类型
                if (statisticParentCode != null) {
                    categoryId = statisticParentCode.getName();
                }
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setParent_page_code(categoryId);// 页面业务类型
                flowStatisticsVo.setParent_category_id(pageBusinessTypes);// 页面名称
            } else {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setParent_page_code(pageBusinessTypes);// 页面业务类型
                flowStatisticsVo.setParent_category_id("");
            }
        }

        for (FlowStatisticsVo flowStatisticsVo : toList) {
            String code = flowStatisticsVo.getPage_code();
            if (code.equals("3XagQ") || code.equals("3TXDD")
                    || code.equals("3DaiZ") || code.equals("3ZhiW")) {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                // 获得相匹配的品类的信息
                String categoryId = CommonParentType
                        .getCategoryShowName(flowStatisticsVo.getCategory_id());
                if (StringUtils.isEmpty(categoryId)) {
                    categoryId = "其它";
                }
                flowStatisticsVo.setCategory_id(categoryId);// 页面名称
                flowStatisticsVo.setPage_code(pageBusinessTypes);// 页面业务类型
            } else if (code.startsWith("3PinD") || code.startsWith("3zhTi")
                    || code.startsWith("3SouS")) {
                String category_id1 = "";
                if (code.startsWith("3PinD")) {
                    category_id1 = "3PinD";
                } else if (code.startsWith("3zhTi")) {
                    category_id1 = "3zhTi";
                } else if (code.startsWith("3SouS")) {
                    category_id1 = "3SouS";
                }
                StatisticCode statisticParentCode = new StatisticCode();
                statisticParentCode.setCode(category_id1);
                // 根据条件查询code对象
                statisticParentCode = statisticCodeService
                        .selectStatisticCode(statisticParentCode);
                String categoryId = "";// 页面业务类型
                if (statisticParentCode != null) {
                    categoryId = statisticParentCode.getName();
                }
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setPage_code(categoryId);// 页面业务类型
                flowStatisticsVo.setCategory_id(pageBusinessTypes);// 页面名称
            } else {
                StatisticCode statisticCode = new StatisticCode();
                statisticCode.setCode(code);
                // 根据条件查询code对象
                statisticCode = statisticCodeService
                        .selectStatisticCode(statisticCode);
                String pageBusinessTypes = "";
                if (statisticCode != null) {
                    pageBusinessTypes = statisticCode.getName();
                }
                flowStatisticsVo.setParent_page_code(pageBusinessTypes);// 页面业务类型
                flowStatisticsVo.setParent_category_id("");
            }
        }

        int defaultLength = 10;
        String[] xAxisDatafName = new String[defaultLength];
        Long amountF = 0l;
        Long otherAmountF = 0l;
        String otherRateF = "0.00";

        Long[] seriesDatat = new Long[defaultLength];
        String[] xAxisDatat = new String[defaultLength];
        String[] xAxisDatatName = new String[defaultLength];
        Long amountT = 0l;
        Long otherAmountT = 0l;
        String otherRateT = "0.00";

        DecimalFormat df = new DecimalFormat("#0.00");
        JSONArray arr = new JSONArray();
        if (fromList != null && !fromList.isEmpty()) {
            int i = 0;
            for (FlowStatisticsVo flowStatistics : fromList) {
                JSONObject o = new JSONObject();
                if (i < defaultLength) {
                    o.put("name", i + 1 + "");
                    o.put("value", flowStatistics.getAmount());
                    arr.add(o);
					/*
					 * String parentPageType = flowStatistics
					 * .getParent_page_type();// 页面技术类型
					 */
                    String parentPageCode = flowStatistics
                            .getParent_page_code();// 页面业务类型
                    String parentCategoryId = flowStatistics
                            .getParent_category_id();// 页面名称
                    if (parentPageCode == null && parentCategoryId == null) {
                        xAxisDatafName[i] = "直接访问";
                    } else {
                        if (StringUtils.isEmpty(parentCategoryId)) {
                            xAxisDatafName[i] = flowStatistics
                                    .getParent_page_code();
                        } else {
                            xAxisDatafName[i] = flowStatistics
                                    .getParent_page_code()
                                    + "-"
                                    + flowStatistics.getParent_category_id();
                        }
                    }
                } else {
                    otherAmountF += flowStatistics.getAmount();
                }
                amountF += flowStatistics.getAmount();
                i++;

            }
            for (FlowStatisticsVo flowStatistics : fromList) {
                if (amountF != 0 && flowStatistics.getAmount() > 0) {
                    String rat = df
                            .format(((double) flowStatistics.getAmount() / amountF) * 100);
                    flowStatistics.setRate(rat);
                    if (StringUtils.isEmpty(flowStatistics
                            .getParent_category_id())) {
                        String tableShowName = flowStatistics
                                .getParent_page_code();
                        flowStatistics.setTableShowName(tableShowName);
                    } else {
                        String tableShowName = flowStatistics
                                .getParent_page_code()
                                + "-"
                                + flowStatistics.getParent_category_id();
                        flowStatistics.setTableShowName(tableShowName);
                    }

                } else {
                    flowStatistics.setRate("0.00");
                }
            }
            if (amountF != 0 && otherAmountF > 0) {
                otherRateF = df.format(((double) otherAmountF / amountF) * 100);
            }

        }
        Long exitAmount = 0l;
        JSONArray arr2 = new JSONArray();
        if (toList != null && !toList.isEmpty()) {
            int i = 1;
            for (FlowStatisticsVo flowStatistics : toList) {
                if (i < defaultLength) {
                    xAxisDatatName[i] = flowStatistics.getPage_code() + "-"
                            + flowStatistics.getCategory_id();
                    net.sf.json.JSONObject o = new net.sf.json.JSONObject();
                    o.put("name", i + 1 + "");
                    o.put("value", flowStatistics.getAmount());
                    arr2.add(o);

                } else {
                    otherAmountT += flowStatistics.getAmount();
                }
                amountT += flowStatistics.getAmount();
                i++;
            }
            for (FlowStatisticsVo flowStatistics : toList) {
                if (amountT != 0 && flowStatistics.getAmount() > 0) {
                    String rat = df
                            .format(((double) flowStatistics.getAmount() / amountT) * 100);
                    flowStatistics.setRate(rat);
                    String tableShowName = flowStatistics.getPage_code() + "-"
                            + flowStatistics.getCategory_id();
                    flowStatistics.setTableShowName(tableShowName);
                } else {
                    flowStatistics.setRate("0.00");
                }

            }
            if (amountT != 0 && otherAmountT > 0) {
                otherRateT = df.format(((double) otherAmountT / amountT) * 100);
            }

        }

        String exitRate = "0.00";
        if (amountF - amountT > 0) {
            exitAmount = amountF - amountT;
            exitRate = df.format(((double) exitAmount / amountF) * 100);
            net.sf.json.JSONObject obj = new net.sf.json.JSONObject();
            obj.put("name", "1");
            obj.put("value", exitAmount);
            xAxisDatatName[0] = "退出流量";
            arr2.add(0, obj);
        }

        FlowStatisticsVo exitFlowStatistics = new FlowStatisticsVo();
        String exitFlowRate = "0.00";
        if (amountF != 0) {
            exitFlowRate = df.format(((double) exitAmount / amountF) * 100);
        }
        if (exitAmount > 0) {
            exitFlowStatistics.setRate(exitFlowRate);
            exitFlowStatistics.setTableShowName("退出流量");
            exitFlowStatistics.setAmount(exitAmount);
            toList.add(0, exitFlowStatistics);
        }

        resultMap.put("amountF", amountF);
        resultMap.put("otherAmountF", otherAmountF);
        resultMap.put("otherRateF", otherRateF);

        resultMap.put("amountT", amountT);
        resultMap.put("otherAmountT", otherAmountT);
        resultMap.put("otherRateT", otherRateT);

        resultMap.put("exitAmount", exitAmount);
        resultMap.put("exitRate", exitRate);
        resultMap.put("fromList", new PageInfo<>(fromList));
        resultMap.put("toList", new PageInfo<>(toList));
        resultMap.put("defaultLength", defaultLength);

        resultMap.put("xAxisDatafName", xAxisDatafName);
        resultMap.put("xAxisDatatName", xAxisDatatName);
        resultMap.put("jsonData1", arr);
        resultMap.put("jsonData2", arr2);
        resultMap.put("productName", productDetail.getProductName());
        return resultMap;
    }

    /**
     * @Title: getListByPage
     * @Description: list分页显示
     * @param @param list
     * @param @param page_size
     * @param @param current_page
     * @param @return 设定文件
     * @return PageInfo<T> 返回类型
     * @throws
     */
	private PageInfo getListByPage(List list, int page_size, int current_page) {
	    if(null == list){
	        return null;
        }
		PageInfo page = new PageInfo<>();
		int totalNum = list.size();
		int pages = totalNum % page_size == 0 ? totalNum / page_size : totalNum
				/ page_size + 1;
		int pageEndRow = 0;
		int pageStartRow = 0;
		if (current_page * page_size < totalNum) {// 判断是否为最后一页 
			pageEndRow = current_page * page_size;
		} else {
			pageEndRow = totalNum;
		}
		pageStartRow = page_size * (current_page - 1) + 1;
		page.setStartRow(pageStartRow);
		page.setEndRow(pageEndRow);
		page.setPageSize(page_size);
		page.setIsFirstPage(current_page == 1);
		page.setIsLastPage(current_page == pages);
		page.setHasNextPage(current_page < pages);
		page.setHasPreviousPage(current_page > 1);
		page.setPages(pages);
		page.setPageNum(current_page);
		page.setTotal(totalNum);

		List resultList = null;
		if (list.size() > 0) {
			resultList = list.subList(pageStartRow-1, pageEndRow);
		}
		page.setList(resultList);
		return page;
	}

    /**
     * @Title: getQueryDate
     * @Description: 查询条件起始时间的处理
     * @param @param choose_date
     * @param @return 设定文件
     * @return Map<String,Date> 返回类型
     * @throws
     */
    private Map<String, Date> getQueryDate(String choose_date) {
        Map<String, Date> map = new HashMap<>();
        DateTimeFormatter formater = DateTimeFormat
                .forPattern("MM/dd/yyyy HH:mm:ss");
        Date beginDate = DateTime.parse(
                choose_date.split("-")[0].trim() + " 00:00:00", formater)
                .toDate();
        Date endDate = DateTime.parse(
                choose_date.split("-")[1].trim() + " 23:59:59", formater)
                .toDate();
        map.put("beginDate", beginDate);
        map.put("endDate", endDate);
        return map;
    }
}
